﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Rapattern.Utilities
{
    public class ScreenShotHelper
    {
        #region winapi
        [DllImport("user32.dll")]
        protected static extern void keybd_event
        (
            byte bVk,// 虚拟键值    
            byte bScan,// 硬件扫描码    
            uint dwFlags,// 动作标识    
            IntPtr dwExtraInfo// 与键盘动作关联的辅加信息    
        );
        [DllImport("user32.dll")]
        protected static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        protected static extern IntPtr GetWindowDC(IntPtr hwnd);
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        protected static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
        [DllImport("gdi32.dll")]
        protected static extern IntPtr CreateCompatibleBitmap(
            IntPtr hdc, // handle to DC
            int nWidth, // width of bitmap, in pixels
            int nHeight // height of bitmap, in pixels
        );
        [DllImport("gdi32.dll")]
        protected static extern IntPtr CreateCompatibleDC(IntPtr hdc);// handle to DC
        [DllImport("gdi32.dll")]
        protected static extern IntPtr SelectObject(
            IntPtr hdc, // handle to DC
            IntPtr hgdiobj // handle to object
        );
        [DllImport("user32.dll")]
        protected static extern bool PrintWindow(
            IntPtr hwnd, // Window to copy,Handle to the window that will be copied. 
            IntPtr hdcBlt, // HDC to print into,Handle to the device context. 
            UInt32 nFlags // Optional flags,Specifies the drawing options. It can be one of the following values. 
        );
        [DllImport("gdi32.dll")]
        protected static extern int DeleteDC(IntPtr hdc);   // handle to DC
        protected struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        };

        #endregion

        /// <summary>
        /// 模拟Print Screen键盘消息，截取全屏图片。  
        /// </summary>
        public static void PrintScreen()
        {
            keybd_event((byte)Keys.PrintScreen, 0, 0x0, IntPtr.Zero);//down 
            Application.DoEvents();
            keybd_event((byte)Keys.PrintScreen, 0, 0x2, IntPtr.Zero);//up  
            Application.DoEvents();
        }
        /// <summary>  
        /// 模拟Alt Print Screen键盘消息，截取当前窗口图片。  
        /// </summary>  
        public static void AltPrintScreen()
        {
            keybd_event((byte)Keys.Menu, 0, 0x0, IntPtr.Zero);
            keybd_event((byte)Keys.PrintScreen, 0, 0x0, IntPtr.Zero);//down  
            Application.DoEvents();
            keybd_event((byte)Keys.PrintScreen, 0, 0x2, IntPtr.Zero);//up  
            keybd_event((byte)Keys.Menu, 0, 0x2, IntPtr.Zero);
            Application.DoEvents();
        }
        /// <summary>
        /// 根据句柄窃取图片
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        public static Bitmap PrintScreen(IntPtr hWnd)
        {
            IntPtr hscrdc = GetWindowDC(hWnd);
            RECT rect;
            rect.left = 1;
            GetWindowRect(hWnd, out rect);
            IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, rect.right - rect.left, rect.bottom - rect.top);
            IntPtr hmemdc = CreateCompatibleDC(hscrdc);
            SelectObject(hmemdc, hbitmap);
            PrintWindow(hWnd, hmemdc, 0);
            Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
            DeleteDC(hscrdc);
            DeleteDC(hmemdc);
            return bmp;
        }
        /// <summary>
        /// 截取屏幕
        /// </summary>
        /// <param name="x">截取屏幕左上角起点 X坐标</param>
        /// <param name="y">截取屏幕左上角起点 Y坐标</param>
        /// <param name="width">截取图片宽度</param>
        /// <param name="height">截取图片高度</param>
        /// <returns></returns>
        public static Bitmap PrintScreen(int x, int y, int width, int height)
        {
            Bitmap b = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(b);
            //g.CompositingQuality = CompositingQuality.HighQuality;
            //g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            //g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            //g.SmoothingMode = SmoothingMode.HighQuality;
            //g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            g.CopyFromScreen(x, y, 0, 0, b.Size);

            return b;
        }
        /// <summary>
        /// 从剪切板获取图片
        /// </summary>
        /// <returns></returns>
        public static Bitmap GetScreenImage()
        {
            Bitmap _bitmap = null;
            try
            {
                if (Clipboard.ContainsImage())
                {
                    _bitmap = (Bitmap)(Clipboard.GetImage().Clone());
                }
                return _bitmap;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
    }
}
